//
// Created by 黄扬航 on 2023/10/1.
//

#include "Client.h"

void Client::SendMesage(struct message Message) {
    SOCKET TempCLient = ShortConnection();
    char*buffer = new char[sizeof(Message)];
    memcpy(buffer,&Message,sizeof(Message));
    int message_length = sizeof(buffer);
    bool Success = false;
    SetTimeOut(TempCLient);
    do {
        send(TempCLient, (const char *)buffer, message_length, 0);
        char *recv_buf;
        recv(TempCLient,recv_buf,sizeof("success"),0);
        strcmp(recv_buf, "success") == 0 ? Success=true : Success = false;
    }while(!Success);
}

SOCKET Client::ShortConnection() {

    SOCKET clientSocket;
    sockaddr_in serverAddr;
    serverAddr.sin_family = AF_INET;
    serverAddr.sin_port = htons(8888);
    memcpy(&serverAddr.sin_addr,ServerIP.c_str(),sizeof(char) * ServerIP.size());
    if (connect(clientSocket, (sockaddr*)&ServerAddr, sizeof(ServerAddr)) == SOCKET_ERROR) {
        std::cerr << "Failed to connect to server" << std::endl;
        closesocket(clientSocket);
        WSACleanup();
        return 1;
    }
    char id;
    recv(clientSocket, (char *)&id, sizeof(id), 0);
    ID= id;
    return clientSocket;

}

//int Client::CheckSendACK(SOCKET TempCLient,int message_length,int ACK_Type) {
//    if(ACK_Type == MSG_ACK)
//    {
//        int ACK;
//        setsockopt(TempCLient,SOL_SOCKET,SO_RCVTIMEO ,(char*)&Recevtimeout,sizeof(Recevtimeout));
//        recv(TempCLient, (char *)ACK, sizeof(ACK), 0);
//        if (ACK == message_length + 1)
//        {
//            closesocket(TempCLient);
//            return 0;
//        }
//        else
//        {
//            std::cerr<<"Error Send Message , Please try again"<<std::endl;
//            return -1;
//        }
//    }
//    else if(ACK_Type == Notify_ACK)
//    {
//        int ACK;
//        setsockopt(TempCLient,SOL_SOCKET,SO_SNDTIMEO ,(char*)&Recevtimeout,sizeof(Recevtimeout));
//        int result = send(TempCLient, (char *)ACK, sizeof(ACK), 0);
//        if(result <=0)
//            return -1;
//            else return 0;
//    }
//}

Client::Client() {
    WSADATA wsaData;
    if (WSAStartup(MAKEWORD(2, 2), &wsaData) != 0) {
        std::cerr << "Failed to initialize Winsock" << std::endl;
        WSACleanup();
    }
    SOCKET clientSocket;
    sockaddr_in serverAddr{};
    serverAddr.sin_family = AF_INET;
    serverAddr.sin_port = htons(8878);
    memcpy(&serverAddr.sin_addr,ServerIP.c_str(),sizeof(char) * ServerIP.size());
    if (connect(clientSocket, (sockaddr*)&ServerAddr, sizeof(ServerAddr)) == SOCKET_ERROR) {
        std::cerr << "Failed to connect to server" << std::endl;
        closesocket(clientSocket);
        WSACleanup();
    }
    ClientSocket = clientSocket;
}

int Client::SetTimeOut(SOCKET &socket) {
    fd_set rset;
    FD_ZERO(&rset);
    FD_SET(socket, &rset);
    return select(socket + 1, &rset, nullptr, nullptr, &timeout);
}

void Client::ReceiveMessage() {
    auto TempClient = ShortConnection();
    SetTimeOut(TempClient);
    bool Done = false;
    do {
        char *recv_buf;
        int result = recv(TempClient,recv_buf,sizeof(message),0);
        if(result <=0 )
        {
            send(TempClient, "Failed!", sizeof ("Failed!"), 0);
            continue;
        }
        else
        {
            send(TempClient, "Success", sizeof ("Success"), 0);
        }
        std::cout<<"New Message:\n"<<recv_buf<<std::endl;
        strcmp(recv_buf, "Done") == 0 ? Done=true : Done = false;
    }while(!Done);
    closesocket(TempClient);
}


